home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1998 / MacHack 1998.toast / Sessions / Why Java Sucks / Newton11 / Rock.java < prev    next >
Encoding:
Text File  |  1998-06-04  |  4.5 KB  |  238 lines  |  [TEXT/R*ch]

  1. /*
  2.     Rock.java - A class for a ruck that sucks.
  3.  
  4.     Copyright (C) 1996-1997 by Michael J. Webb
  5. */
  6.  
  7. // Imports
  8.  
  9. import java.awt.Color;
  10. import java.awt.Graphics;
  11. import java.util.Random;
  12.  
  13. import java.io.EOFException;
  14. import java.io.PrintStream;
  15. import java.io.StreamTokenizer;
  16.  
  17. import NewtonCanvas;
  18.  
  19. /** A class for a rock that sucks.
  20.  */
  21. class Rock
  22. {
  23.  
  24. /* Public Members. */
  25.  
  26.     public static java.util.Random rockDice = new java.util.Random();
  27.  
  28.     public double rockX;
  29.     public double rockY;
  30.     public double rockZ;
  31.  
  32.     public double rockOldX;
  33.     public double rockOldY;
  34.     public double rockOldZ;
  35.  
  36.     public double rockDx;
  37.     public double rockDy;
  38.     public double rockDz;
  39.  
  40.     public double rockMass;
  41.     public int rockSize;
  42.  
  43.     public int rockId;
  44.  
  45.     public NewtonCanvas rockCanvas;
  46.  
  47. /* Public methods. */
  48.  
  49.     /** Main constructor; takes a rock ID and the parent canvas.
  50.      */
  51.     public Rock
  52.     (
  53.         int theId,
  54.         NewtonCanvas theCanvas
  55.     )
  56.     {
  57.         this.rockCanvas = theCanvas; 
  58.         this.rockId = theId;
  59.         Rock.seed(this);
  60.     }
  61.  
  62.     /** Main drawing method; draws an oval of the right size.
  63.      */
  64.     public void drawSelfShape(Graphics g)
  65.     {
  66.  
  67.         if
  68.             (
  69.                 (rockX >= 0.0) &&
  70.                 (rockY >= 0.0) &&
  71.                 (rockX < rockCanvas.getSize().width) &&
  72.                 (rockY < rockCanvas.getSize().height)
  73.             )
  74.         {
  75.             g.setColor(Color.white);
  76.  
  77.             g.fillOval
  78.             (
  79.                 (int)(java.lang.Math.floor(rockX)) - rockSize,
  80.                 (int)(java.lang.Math.floor(rockY)) - rockSize,
  81.                 2 * rockSize,
  82.                 2 * rockSize
  83.             );
  84.         }
  85.  
  86.         rockOldX = rockX;
  87.         rockOldY = rockY;
  88.         rockOldZ = rockZ;
  89.     }
  90.  
  91.     /** Compute gravatational effect for the current tick and move the rock.
  92.      */
  93.     public void computeValues()
  94.     {
  95.         for (int i = 0; i < rockCanvas.myNumRocks; i++)
  96.         {
  97.             if (i != rockId)
  98.             {
  99.                 this.Suck(rockCanvas.myRocks[i]);
  100.             }
  101.         }
  102.  
  103.         this.rockX = this.rockOldX + this.rockDx;
  104.         this.rockY = this.rockOldY + this.rockDy;
  105.         this.rockZ = this.rockOldZ + this.rockDz;
  106.     }
  107.  
  108.     /** Dump a rock to a print stream.
  109.      */
  110.     public void store(java.io.PrintStream stream)
  111.     {
  112.         stream.print(rockMass);
  113.         stream.print('\t');
  114.         stream.print(rockX);
  115.         stream.print('\t');
  116.         stream.print(rockY);
  117.         stream.print('\t');
  118.         stream.print(rockZ);
  119.         stream.print('\t');
  120.         stream.print(rockDx);
  121.         stream.print('\t');
  122.         stream.print(rockDy);
  123.         stream.print('\t');
  124.         stream.print(rockDz);
  125.         stream.println();
  126.     }
  127.  
  128.     /** Initialize a rock from a token stream.
  129.      */
  130.     public void restore(StreamTokenizer tokens)
  131.         throws EOFException
  132.     {
  133.         try
  134.         {
  135.             rockMass = readDoubleToken(tokens);
  136.             rockX = readDoubleToken(tokens);
  137.             rockY = readDoubleToken(tokens);
  138.             rockZ = readDoubleToken(tokens);
  139.             rockDx = readDoubleToken(tokens);
  140.             rockDy = readDoubleToken(tokens);
  141.             rockDz = readDoubleToken(tokens);
  142.  
  143.         }
  144.         catch (Throwable e)
  145.         {
  146.             throw(new EOFException());
  147.         }
  148.     }
  149.  
  150. /* Public Static Methods. */
  151.  
  152.     /** Initializ a rock with random initial values.
  153.      */
  154.     public static void seed(Rock aRock)
  155.     {
  156.         aRock.rockX = (rockDice.nextDouble() * 300.0) + 50.0;
  157.         aRock.rockY = (rockDice.nextDouble() * 300.0) + 50.0;
  158.         aRock.rockZ = (rockDice.nextDouble() * 20.0) - 10.0;
  159.  
  160.         aRock.rockOldX = aRock.rockX;
  161.         aRock.rockOldY = aRock.rockY;
  162.         aRock.rockOldZ = aRock.rockZ;
  163.  
  164.         aRock.rockDx = rockDice.nextGaussian() * 0.5;
  165.         aRock.rockDy = rockDice.nextGaussian() * 0.5;
  166.         aRock.rockDz = rockDice.nextGaussian() * 0.5;
  167.  
  168.         aRock.rockMass = 1.0 + java.lang.Math.abs(rockDice.nextGaussian());
  169.         aRock.rockMass = aRock.rockMass * aRock.rockMass;
  170.  
  171.         aRock.rockSize =
  172.             (int)
  173.             java.lang.Math.floor
  174.             (
  175.                 java.lang.Math.pow(aRock.rockMass, (1.0 / 3.0))
  176.             );
  177.     }
  178.  
  179. /* Private methods. */
  180.  
  181.     /** Compute acceleration effect on the rock for the current frame.
  182.      */
  183.     private void Suck(Rock theRock)
  184.     {
  185.         double            distance;
  186.         double            df;
  187.         double            dv;
  188.         double            dx = this.rockOldX - theRock.rockOldX;
  189.         double            dy = this.rockOldY - theRock.rockOldY;
  190.         double            dz = this.rockOldZ - theRock.rockOldZ;
  191.     
  192.         distance =
  193.             java.lang.Math.max
  194.             (
  195.                 1.0,
  196.                 java.lang.Math.sqrt((dx*dx) + (dy*dy) + (dz*dz))
  197.             );
  198.     
  199.         dv = this.rockMass / (distance*distance);
  200.         df = dv / distance;
  201.  
  202.         theRock.rockDx += df * dx;
  203.         theRock.rockDy += df * dy;
  204.         theRock.rockDz += df * dz;
  205.     }
  206.  
  207.     /** Get a double value from a token stream.
  208.      */
  209.     private double readDoubleToken(StreamTokenizer tokens)
  210.         throws EOFException
  211.     {
  212.         double    val = 0.0;
  213.  
  214.         try
  215.         {
  216.             int        tok = tokens.nextToken();
  217.  
  218.             if (tok == StreamTokenizer.TT_NUMBER)
  219.             {
  220.                 String    token = new String(tokens.toString());
  221.                 String num = new String(token.substring(8));
  222.                 val = Double.valueOf(num).doubleValue();
  223.             }
  224.             else
  225.             {
  226.                 throw(new EOFException());
  227.             }
  228.         }
  229.         catch (Throwable e)
  230.         {
  231.             throw(new EOFException());
  232.         }
  233.  
  234.         return val;
  235.     }
  236. }
  237.  
  238.